#ifndef _PROCESS_POOL_HPP
#define _PROCESS_POOL_HPP
#include"task.hpp"
#include<iostream>
#include<vector>
#include<string>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<signal.h>
#include<sys/ipc.h>




class Channel
{
public:
    Channel(int wfd, pid_t supid)
        : _wfd(wfd), _subid(supid)
        {
            _name = "Channel_" + std::to_string(wfd) + "_" + std::to_string(supid);
        }
    ~Channel(){}
    int getWfd() const { return _wfd; }
    pid_t getSupid() const { return _subid; }
    const std::string& getName() const { return _name; }

    void Send(int code)
    {
        int n = write(_wfd, &code, sizeof(code));
        if(n < 0)
        {
            std::cerr << "write error" << std::endl;
        }
    }

    void Close()
    {
        close(_wfd);
    }

    void Wait()
    {
        pid_t pid = waitpid(_subid, NULL, 0);
        if(pid < 0)
        {
            std::cerr << "waitpid error" << std::endl;
        }
    }

private:
    int _wfd;
    pid_t _subid;
    std::string _name;
};


class ChannelManager
{
public:
    ChannelManager()
    : _nextWfd(0)
    {}
    Channel &select()
    {
        auto & it = _channels[_nextWfd];
        _nextWfd = (_nextWfd + 1) % _channels.size();
        return it;
    }
    void Insert(int wfd, pid_t subid)
    {
        _channels.emplace_back(wfd, subid);
    }
    void PrintChannels()
    {
        for(auto & it : _channels)
        {
            std::cout<<it.getName()<<std::endl;
        }
    }

    void closeAll()
    {
        for(auto & it : _channels)
        {
            it.Close();
        }
    }

    void StopAndWaitSubProcess()
    {
        for(auto & it : _channels)
        {
            it.Close();
            it.Wait();
        }
    }


    ~ChannelManager(){}

private:
    std::vector<Channel> _channels;
    int _nextWfd;  // 循环遍历下一个fd 保持负载均衡

};

const int defaultProcessNum = 3;

class ProcessPool
{
public:
    ProcessPool(int num)
    : _processNum(num)
    {
        _task.add_task(task1);
        _task.add_task(task2);
        _task.add_task(task3);
    }
    void work(int rfd)
    {
        while (1)
        {
            int code = 0;
            size_t n = read(rfd, &code, sizeof(code));
            if(n < 0)
            {
                std::cerr << "read error" << std::endl;
                break;
            }
            else if(n == 0)
            {
                std::cerr << "子进程退出" << std::endl;
                break;
            }
            else
            {
                std::cout<<"子进程"<<getpid()<<"收到任务"<<std::endl;
                _task.Excute(code);
            }
        }
    }


    bool start()
    {
        for(int i = 0; i < _processNum; i++)
        {
            //  创建管道
            int piped[2] = {0};
            int n = pipe(piped);
            if(n < 0)
            {
                std::cerr << "create pipe error" << std::endl;
                return false;
            }
            // fork 子进程
            pid_t subid = fork();
            if(subid < 0)
            {
                std::cerr << "fork error" << std::endl;
                return false;
            }
            else if(subid == 0)
            {
                // 子进程
                close(piped[1]);
                _channelManager.closeAll();
                work(piped[0]);// 子进程处理任务
                close(piped[0]);
                exit(0);
            }
            else
            {
                // 父进程
                close(piped[0]);
                _channelManager.Insert(piped[1], subid);
            }
        }
        return true;
    }

    void Debug()
    {
        _channelManager.PrintChannels();
    }

    void run()
    {
        int taskcode = _task.code();
        auto & channel = _channelManager.select();
        // 发送任务
        channel.Send(taskcode);
    }

    void stop()
    {
        _channelManager.StopAndWaitSubProcess();
    }

    ~ProcessPool(){}

private:
    ChannelManager _channelManager;
    int _processNum;
    Task _task;
};



#endif   